<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/3/19
 * Time: 14:18
 */

namespace Six\Core;

use mysql_xdevapi\Exception;
use Six\Core\Event\Event;
use Swoole\Http\Server;

class Http
{
    public function run()
    {

        $config = Config::get_instance();
        $config->load(); //载入配置文件

        $setting = $config->get('http');
        $this->server = new Server($setting['host'], $setting['port']);
        $this->server->set($setting['swoole_setting']);
        $this->server->on('request', [$this, 'request']);
        $this->server->on('Start', [$this, 'start']);
        $this->server->on('workerStart', [$this, 'workerStart']);

        //tcp服务端口监听
        if ((int)$setting['tcpable'] === 1) {
            $tcp = $config->get('tcp');
            $this->registerTcp($tcp);
        }

        $this->server->start();
    }

    public function registerTcp($tcp)
    {
        $rpc = new Rpc();
        $rpc->listen($this->server, $tcp);
    }

    public function request($request, $response)
    {
        try {
            //加载默认路由
            Route::get_instance()->dispatch($request, $response);
        } catch (\Exception $e) { //程序异常
            var_dump($e->getMessage());
        }
    }

    public function start()
    {
        $reload = Reload::get_instance();
        $reload->watch = [CONFIG_PATH, FRAME_PATH, APP_PATH];
        $reload->md5Flag = $reload->getMd5();

        //主动收集listen时间
        $this->collectEvent();
//        $obj = new StartListener();
//        \Six\Core\Event\Event::register('start', [$obj, 'handle']);

        //定时器
        swoole_timer_tick(3000, function () use ($reload) {
            if ($reload->reload()) {
                $this->server->reload(); //重启
            }
        });

        \Six\Core\Event\Event::trigger('start');

    }

    public function workerStart($server, $worker_id)
    {
        //支持热加载
        $config = Config::get_instance();
        $config->loadLazy();
        //连接redis、连接数据库

        if ($worker_id == 0) {
            Event::register('workerStart', ['server' => $server, 'worker_id' => $worker_id]);
        }

        //加载路由配置文件
        include_once APP_PATH . '/route.php';
    }

    public function collectEvent()
    {
        $theFiles = glob(EVENT_PATH . '/*.php');
        if (!empty($theFiles)) {
            foreach ($theFiles as $dir => $fileName) {
                include_once $fileName;
                $fileName = explode('/', $fileName);
                $className = explode('.', end($fileName))[0];
                $nameSpace = 'App\\Listener\\' . $className;
                if (class_exists($nameSpace)) {
                    $obj = new $nameSpace;
                    $re = new \ReflectionClass($obj);
                    $str = $re->getDocComment();
                    if (strlen($str) < 2) {
                        throw new Exception('没有按照规则定义事件名称');
                    } else {
                        preg_match("/@Listener\('(.*)'\)/i", $str, $eventName);
                        if (empty($eventName)) {
                            throw new Exception('没有按照规则定义事件名称');
                        }
                        Event::register($eventName[1], [$obj, 'handle']);
                    }
                }
            }
        }
//        \Six\Core\Event\Event::register('start', [$obj, 'handle']);

    }
}